package com.ebt.m.customer.fakeDialog.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ebt.m.R;
import com.ebt.m.customer.constant.CustomerConstant;
import com.ebt.m.customer.fakeDialog.drawable.FakeDialogBackgoundDrawable;

import java.util.ArrayList;

/**
 * 使用的anim listener，待优化
 */
@SuppressLint("NewApi")
public class FakeDialogView extends RelativeLayout implements View.OnClickListener{

    public static class ChildModel{

        public String text;
        public int idImageSrc = -1;

        public ChildModel(String text, int idImageSrc){
            this.text = text;
            this.idImageSrc = idImageSrc;
        }
    }

    public interface OnFakeDialogClickListener{
        void onFakeDialogBackgroundClick();
        void onFakeDialogChildrenClick(int index);
    }

    private static final int DEFAULT_COLOR_BACKGROUND_FAKE_DIALOG = 0x00000000;
    private static final int DEFAULT_GAP_V = 24;
    private static final int DEFAULT_GAP_H = 24;

    private static final int DEFAULT_DURATION_BACKGROUND_FAKE_DIALOG_SHOW = 300;
    private static final int DEFAULT_DURATION_BACKGROUND_FAKE_DIALOG_HIDE = 200;

    private int mColorBg = DEFAULT_COLOR_BACKGROUND_FAKE_DIALOG;
    private long mDurationBgShow = DEFAULT_DURATION_BACKGROUND_FAKE_DIALOG_SHOW;
    private long mDurationBgHide = DEFAULT_DURATION_BACKGROUND_FAKE_DIALOG_HIDE;
    private float mBgShowRatioFrom = 0.4f;
    private float mBgShowRatioTo = 1f;
    private float mBgShowRatioSpan = mBgShowRatioTo - mBgShowRatioFrom;

    private Context mContext;
    private OnFakeDialogClickListener mOnFakeDialogClickListener;

    private ArrayList<ChildModel> mChildrenModels;
    private ArrayList<View> imageViews = new ArrayList<View>();
    private ArrayList<TextView> textViews  = new ArrayList<TextView>();

    public FakeDialogView(Context context) {
        this(context, null);
    }

    public FakeDialogView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FakeDialogView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init();
    }

    private void init(){
        this.setOnClickListener(this);
        this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    public void onClick(View v) {
        dismiss();
        if(mOnFakeDialogClickListener != null){
            if(v == this){
                mOnFakeDialogClickListener.onFakeDialogBackgroundClick();
            }else{
                this.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mOnFakeDialogClickListener.onFakeDialogChildrenClick((v.getId() - R.id.customer_view_trans + 1) / 2);
                    }
                }, mDurationBgHide);
            }
        }
    }

    private ArrayList<Point> imageviewsTrans = new ArrayList<>();
    private View mForegroundView;

    public void addChildrenViews(View foregroundView, ArrayList<ChildModel> childrenModels,
                                 OnFakeDialogClickListener fakeDialogClickListener){
        if(mContext == null || !(mContext instanceof Activity)){
            return;
        }
        mForegroundView = foregroundView;
        mOnFakeDialogClickListener = fakeDialogClickListener;

        int gapVPx = dip2px(mContext, DEFAULT_GAP_V);

        if(childrenModels != null && childrenModels.size() > 0){
            mChildrenModels = childrenModels;
            View viewTran = new View(mContext);
            viewTran.setId(R.id.customer_view_trans);
            ViewGroup.MarginLayoutParams lp = (MarginLayoutParams)foregroundView.getLayoutParams();
            LayoutParams viewTranLP = new LayoutParams(lp);
            viewTranLP.height = foregroundView.getMeasuredHeight();
            viewTranLP.width = foregroundView.getMeasuredWidth();

            viewTranLP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            viewTranLP.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            viewTran.setLayoutParams(viewTranLP);
            this.addView(viewTran);

            int tranWidth  = viewTranLP.width;
            int tranHeight = viewTranLP.height;
            int[] viewSizeImage = new int[2];
            int[] viewSizeText  = new int[2];

            int size = childrenModels.size();
            for(int i = 0; i < size; i++){
                int idBase = R.id.customer_view_trans + i * 2;

                ImageView imageView = new ImageView(mContext);
                imageView.setId(idBase + 1);
                imageView.setImageResource(childrenModels.get(i).idImageSrc);
                imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

                viewSizeImage[0] = dip2px(mContext, 48);
                viewSizeImage[1] = dip2px(mContext, 48);

                RelativeLayout.LayoutParams imageViewLP = new RelativeLayout.LayoutParams(viewSizeImage[0], viewSizeImage[1]);
                imageViewLP.addRule(RelativeLayout.ALIGN_LEFT, R.id.customer_view_trans);
                imageViewLP.leftMargin = (tranWidth - viewSizeImage[0])/2;
                imageViewLP.addRule(RelativeLayout.ALIGN_TOP, R.id.customer_view_trans);
                imageViewLP.topMargin = (tranHeight - viewSizeImage[1])/2;

                imageView.setLayoutParams(imageViewLP);
                imageView.setOnClickListener(this);
                imageView.setVisibility(View.INVISIBLE);
                if(size == 4){
                    int radius = (int)(viewSizeImage[0] * 2.2);
                    switch (i){
                        case 0:
                            imageviewsTrans.add(new Point(-radius, 0));
                            break;
                        case 1:
                            imageviewsTrans.add(new Point((int)(-radius * 0.84f), (int)(-radius * 0.5f)));
                            break;
                        case 2:
                            imageviewsTrans.add(new Point((int)(-radius * 0.5f), (int)(-radius * 0.84f)));
                            break;
                        case 3:
                            imageviewsTrans.add(new Point(0, -radius));
                            break;
                    }
                }
                imageViews.add(imageView);
                this.addView(imageView);
            }
        }
    }

    private void setBackgroundForChild(View view, Drawable drawableTarget, Drawable drawableDefault){
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            if (drawableTarget != null) {
                view.setBackgroundDrawable(drawableTarget);
            }else if(drawableDefault != null){
                view.setBackgroundDrawable(drawableDefault);
            }
        } else {
            if (drawableTarget != null) {
                view.setBackground(drawableTarget);
            } else if(drawableDefault != null){
                view.setBackground(drawableDefault);
            }
        }
    }

    public void dismiss(){
        if (mValueAnimator != null && mValueAnimator.isRunning()){
            float f = mValueAnimator.getAnimatedFraction();
            mValueAnimator.cancel();
            mValueAnimator.setFloatValues(f, 0);
            mValueAnimator.setDuration((long)(ACTION_DURATION * f));
            mValueAnimator.removeAllUpdateListeners();
            mValueAnimator.removeAllListeners();
            mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float currF = (Float)valueAnimator.getAnimatedValue();
                    for(int i = 0; i < size; i++){
                        imageViews.get(i).setTranslationX(imageviewsTrans.get(i).x * currF);
                        imageViews.get(i).setTranslationY(imageviewsTrans.get(i).y * currF);
                        if (mForegroundView != null){
                            mForegroundView.setRotation(CustomerConstant.UI.ACTION_BUTTON_ROTATION * currF);
                            mForegroundView.setClickable(false);
                        }
                    }
                }
            });

            mValueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    if (mForegroundView != null) {
                        mForegroundView.setClickable(true);
                    }
                    if (FakeDialogView.this != null && FakeDialogView.this.getParent() != null) {
                        ((ViewGroup) (FakeDialogView.this.getParent())).removeView(FakeDialogView.this);
                    }
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }
            });
            mValueAnimator.start();
        }else{
            if (mValueAnimator == null){
                mValueAnimator = ValueAnimator.ofFloat(1 ,0);
            }else {
                mValueAnimator.setFloatValues(1, 0);
            }
            mValueAnimator.setDuration(ACTION_DURATION);
            mValueAnimator.removeAllUpdateListeners();
            mValueAnimator.removeAllListeners();
            mValueAnimator.setInterpolator(new OvershootInterpolator());

            mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float currF = (Float)valueAnimator.getAnimatedValue();
                    FakeDialogView.this.setAlpha(currF);
                    if (mForegroundView != null){
                        mForegroundView.setRotation(CustomerConstant.UI.ACTION_BUTTON_ROTATION * currF);
                        mForegroundView.setClickable(false);
                    }
                }
            });
            mValueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    if (mForegroundView != null) {
                        mForegroundView.setClickable(true);
                    }
                    if (FakeDialogView.this != null && FakeDialogView.this.getParent() != null) {
                        ((ViewGroup) (FakeDialogView.this.getParent())).removeView(FakeDialogView.this);
                    }
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                }

                @Override
                public void onAnimationRepeat(Animator animator) {
                }
            });
            mValueAnimator.start();
        }


        /*final AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
        alphaAnimation.setDuration(mDurationBgHide);

        this.setVisibility(View.VISIBLE);
        this.startAnimation(alphaAnimation);
        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                ((ViewGroup)(FakeDialogView.this.getParent())).removeView(FakeDialogView.this);
            }
        });*/
    }

    public void setFakeDialogBackgroundColor(int colorBg){
        mColorBg = colorBg;
    }

    private int size = 0;
    private ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0, 1);
    //TODO
    private State state = State.Hidden;
    private enum State{
        Showing, Shown, Hiding, Hidden
    }

    private static final int ACTION_DURATION = 320;

    public void show(boolean anim){
        ColorDrawable colorDrawable = new ColorDrawable(mColorBg);

        final FakeDialogBackgoundDrawable backgroundDrawable = new FakeDialogBackgoundDrawable(colorDrawable);

        int measuredWidth = this.getMeasuredWidth();
        int measuredHeight = this.getMeasuredHeight();

        backgroundDrawable.setBounds(this.getPaddingLeft(), this.getPaddingTop(),
                measuredWidth - this.getPaddingRight(), measuredHeight - this.getPaddingBottom());

        this.setBackground(backgroundDrawable);

        if(mChildrenModels != null && !mChildrenModels.isEmpty()){
            size = mChildrenModels.size();
        }

        if(!anim){
            this.setVisibility(View.VISIBLE);
            backgroundDrawable.setRadiusRatio(1);
            mValueAnimator.setDuration(ACTION_DURATION);
            mValueAnimator.setInterpolator(new OvershootInterpolator());
            mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    float currF = (Float)valueAnimator.getAnimatedValue();

                    for(int i = 0; i < size; i++){
                        imageViews.get(i).setTranslationX(imageviewsTrans.get(i).x * currF);
                        imageViews.get(i).setTranslationY(imageviewsTrans.get(i).y * currF);
                        if (mForegroundView != null){
                            mForegroundView.setRotation(CustomerConstant.UI.ACTION_BUTTON_ROTATION * currF);
                            mForegroundView.setClickable(false);
                        }
                    }
                }
            });
            mValueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                    for(int i = 0; i < size; i++){
                        imageViews.get(i).setVisibility(View.VISIBLE);
                    }
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    if (mForegroundView != null) {
                        mForegroundView.setClickable(true);
                    }
                }

                @Override
                public void onAnimationCancel(Animator animator) {
                }

                @Override
                public void onAnimationRepeat(Animator animator) {}
            });

            mValueAnimator.start();
            return;
        }

        ValueAnimator va = ValueAnimator.ofFloat(0, 1);
        va.setInterpolator(new AccelerateInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator value) {
                float currRatio = (Float)value.getAnimatedValue();
                for(int i = 0; i < size; i++) {
                    View iv = imageViews.get(i);
                    Point p = imageviewsTrans.get(i);
                    iv.setTranslationX(p.x * currRatio);
                    iv.setTranslationY(p.y * currRatio);
                }
            }
        });
        va.addListener(new Animator.AnimatorListener() {

            @Override
            public void onAnimationStart(Animator animation) {
                if(size > 0){
                    for(int i = 0; i < size; i++){
                        View iv = imageViews.get(i);

                        ScaleAnimation sa = new ScaleAnimation(0.7f, 1f, 0.7f, 1f,
                                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
                                ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
                        sa.setInterpolator(new DecelerateInterpolator(3));
                        sa.setDuration(mDurationBgShow);
                        iv.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                iv.setVisibility(View.VISIBLE);
                                iv.startAnimation(sa);
                            }
                        }, mDurationBgShow / size * i);
                    }
                }
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }
        });

        va.setDuration(mDurationBgShow);
        this.setVisibility(View.VISIBLE);
        va.start();

    }

    float span = 0.5f;
    float delta = 0;
    float base = 0.6f;

    private void showChild(int childrenSize, float ratio, long duration){

        for(int i = 0; i < size; i++){
            float deltaI = delta * (i + 1);
            if(ratio < deltaI){
                imageViews.get(i).setScaleX(0);
                imageViews.get(i).setScaleY(0);
            }else if(deltaI <= ratio && ratio < deltaI + span){
                float ratioI = (ratio - deltaI)/span;
                float ratioII = base + (1 - base) * ratioI;
                imageViews.get(i).setScaleX(ratioII);
                imageViews.get(i).setScaleY(ratioII);
            }else{
                imageViews.get(i).setScaleX(1);
                imageViews.get(i).setScaleY(1);
            }
        }
    }

    private void showChild(long duration, int childrenSize){

        long durationEle = duration / childrenSize;

        for(int i = 0; i < childrenSize; i++){
            final ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 1f, 0.5f, 1f,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            scaleAnimation.setDuration(durationEle * 3);
            scaleAnimation.setInterpolator(new DecelerateInterpolator(3));

            final View imageView = imageViews.get(i);
            imageView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    imageView.setVisibility(View.VISIBLE);
                    imageView.startAnimation(scaleAnimation);
                }
            }, durationEle * i / 4);

            final AlphaAnimation alphaAnimation = new AlphaAnimation(0.5f, 1f);
            alphaAnimation.setDuration(durationEle * 3);
        }
    }

    //animation
    public void setChildShowAnimation(){

    }

    public void setChildDismissAnimation(){

    }

    public void setDialogShowAnimation(){

    }

    public void setDialogDismissAnimation(){

    }

    public int dip2px (Context context, float dipValue){
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(dipValue*scale+0.5f);
    }

    public int px2dp(Context context, float pxValue){
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(pxValue/scale+0.5f);
    }

    private void getMeasuredSize(View view, int[] size){
        int widthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        view.measure(widthSpec, heightSpec);
        size[0] = view.getMeasuredWidth();
        size[1] = view.getMeasuredHeight();
    }

    public void setOnFakeDialogClickListener(OnFakeDialogClickListener onFakeDialogClickListener){
        this.mOnFakeDialogClickListener = onFakeDialogClickListener;
    }

}